package com.airport.schedule.model;

import com.airport.schedule.util.StringUtils;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class FlightGate {

    private static final String NEAR_GATE = "近机位";
    private static final String FAR_GATE = "远机位";
    private static final String NO_RESTRICT = "无限制";
    private static final String INTERNATIONAL = "国际";
    private static final String INTERNAL = "国内";

    private final String flightGateId;
    private final String runwayIn; // 滑入跑道  为空的时候代表无限制
    private final String runwayOut; // 滑出跑道
    private final String desc;

    private final Set<String> acceptFlightTasks;
    private final Set<String> acceptAirCompanies;
    private final Set<String> acceptAirplaneTypes;

    private final byte acceptFlightType; // 1国内 2国际 3国内/国际

    private final boolean isNearGate; // 是否近机位
    private final boolean isNormal; // 区分正常机位和采取临时措施的机位
    private final boolean hasNoRunwayConflict; // 特殊机位 滑道永远不会有冲突
    private final AdHocRule rule; // 临时措施限制规则


    public FlightGate(String flightGateId, String acceptFlightType, String gateAttr,
                      String runwayIn, String runwayOut, String flightTask, String flightCompanies,
                      String airplaneType, AdHocRule rule) {
        this.flightGateId = flightGateId.trim();
        this.hasNoRunwayConflict = StringUtils.isEmpty(runwayIn) && StringUtils.isEmpty(runwayOut);
        if(hasNoRunwayConflict()) {
            this.runwayIn = NO_RESTRICT;
            this.runwayOut = NO_RESTRICT;
        }else {
            this.runwayIn = runwayIn.trim();
            this.runwayOut = runwayOut.trim();
        }
        if(gateAttr.trim().equals(NEAR_GATE)) {
            this.isNearGate = true;
        }else if(gateAttr.trim().equals(FAR_GATE)){
            this.isNearGate = false;
        }else{
            throw new IllegalArgumentException("gateId = "+flightGateId+" " +
                    "has unknown gate attribute = "+gateAttr);
        }
        this.acceptAirplaneTypes = new HashSet<>(Arrays.asList(airplaneType.split(",")));
        if(!StringUtils.checkAllNumberOrAlphabet(acceptAirplaneTypes)) {
            throw new IllegalArgumentException("gateId = "+flightGateId+" has illegal airplaneType code!");
        }
        if(rule != null) {
            this.isNormal = false;
            this.rule = rule;
            this.acceptFlightType = -1;
            this.acceptAirCompanies = null;
            this.acceptFlightTasks = null;
            desc = "临时机位号:"+flightGateId+" "+gateAttr+" 跑道:"+runwayIn+"<=>"+runwayOut+" " +
                    " 机型:"+airplaneType+" 影响机位: "+rule;
        }else{
            this.isNormal = true;
            this.rule = null;
            if(acceptFlightType.trim().equals(INTERNAL)) {
                this.acceptFlightType = 1;
            }else if(acceptFlightType.trim().equals(INTERNATIONAL)) {
                this.acceptFlightType = 2;
            }else {
                this.acceptFlightType = 3;
            }
            this.acceptAirCompanies = new HashSet<>(Arrays.asList(flightCompanies.split(",")));
            if(!StringUtils.checkAllNumberOrAlphabet(acceptAirCompanies)) {
                throw new IllegalArgumentException("gateId = "+flightGateId+" has illegal airCompany code!");
            }

            this.acceptFlightTasks = new HashSet<>(Arrays.asList(flightTask.split(",")));
            if(!StringUtils.checkAllNumberOrAlphabet(acceptFlightTasks)) {
                throw new IllegalArgumentException("gateId = "+flightGateId+" has illegal flightTask code!");
            }
            desc = "机位号:"+flightGateId+" "+acceptFlightType+" "+gateAttr+" 跑道:"+runwayIn+"<=>"+runwayOut+" " +
                    "任务:"+flightTask+" 公司:"
                    +flightCompanies+" 机型:"+airplaneType;
        }
    }

    public boolean acceptFlight(Flight flight) {
        if(isNormal) {
            return acceptAirCompanies.contains(flight.getAirCompany())
                    && acceptAirplaneTypes.contains(flight.getAirplaneType())
                    && acceptFlightTasks.contains(flight.getFlightTask())
                    && ((acceptFlightType & flight.getFlightType()) > 0);
        }else{
            return acceptAirplaneTypes.contains(flight.getAirplaneType());
        }
    }

    public AdHocRule getRule() {
        return this.rule;
    }

    public String getRunwayIn() {
        return runwayIn;
    }

    public String getRunwayOut() {
        return runwayOut;
    }

    public String getFlightGateId() {
        return flightGateId;
    }

    public boolean isNearGate() {
        return isNearGate;
    }

    public boolean hasNoRunwayConflict() {
        return hasNoRunwayConflict;
    }

    public boolean isAdHocGate() {
        return !isNormal;
    }

    public String toString() {
        return this.desc;
    }

}
